package com.socket.server.custom;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.socket.secure.util.MappingUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/**
 * 请求日志处理切面AOP
 */
@Slf4j
@Aspect
@Component
@RequiredArgsConstructor
public class RequestAspect {
    private final HttpServletRequest request;

    /**
     * 定义切点&切点范围
     */
    @Pointcut("(execution(* com.socket.server.controller.*.*.*(..)) || execution(* com.socket.server.controller.*.*(..)))")
    public void pointController() {
    }

    @Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping) || @annotation(org.springframework.web.bind.annotation.PostMapping)")
    public void pointMapping() {
    }

    @Around(value = "pointController() && pointMapping()", argNames = "point")
    public Object aroundLog(ProceedingJoinPoint point) throws Throwable {
        String strArgs = StrUtil.unWrap(JSONUtil.toJsonStr(point.getArgs()), "[", "]");
        log.debug("WebLog => URL: {} | Args: {}", request.getRequestURI(), strArgs);
        log.debug("WebLog => Class: {}", point.getSignature().getDeclaringTypeName());
        long time = System.currentTimeMillis();
        Object result = point.proceed();
        long offset = System.currentTimeMillis() - time;
        log.debug("WebLog => Response: {} | Time: {}ms", MappingUtil.toJSONString(result), offset);
        return result;
    }
}
